package com.itheima.controller;


import com.itheima.entity.Result;
import com.itheima.pojo.Admin;
import com.itheima.service.AdminService;
import com.itheima.utils.CookieUtils;
import com.itheima.utils.IpUtils;
import com.itheima.utils.TokenDecode;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@RestController
@CrossOrigin
@RequestMapping("/auth")
public class AuthController {

    @Autowired
    private AdminService adminService;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Value("${sign}")
    private String sign;

    @Autowired
    private TokenDecode tokenDecode;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private RedisTemplate redisTemplate;

    private static final String ADMIN = "admin";

    /**
     * 登录功能
     *
     * @param username
     * @param password
     * @param isRememberMe
     * @return
     */
    @PostMapping("/login")
    public Result login(String username, String password, Integer isRememberMe) {
        System.out.println(username);
        System.out.println(password);
        System.out.println(isRememberMe);
        Admin admin = adminService.findByUsername(username);
        String _password = admin.getPassWord();
        boolean flag = bCryptPasswordEncoder.matches(password, _password);
        if (flag) {
            JwtBuilder jwtBuilder = Jwts.builder()
                    .setId(admin.getUid())                                  //将用户id设置成唯一编号jti
                    .setSubject("login")                            //设置主题
                    .setIssuedAt(new Date())                        //设置token生成时间
                    .claim("username", admin.getUserName())  //将username放入token中,以便于后期从登陆信息中获取
                    .signWith(SignatureAlgorithm.HS256, sign);                    //设置签名,使用HS256算法,并设置SecretKey字符串

            Map map = new HashMap();
            map.put("token", jwtBuilder.compact());
            //不设置过期时间,浏览器关闭后cookie丢弃 ,将token设置成cookie信息
            CookieUtils.setCookie("token", jwtBuilder.compact(), -1);
            //记住我
            if (isRememberMe != null && isRememberMe == 1) {
                //cookie保存30天
                CookieUtils.setCookie("username", admin.getUserName(), 60 * 60 * 24 * 30);
                CookieUtils.setCookie("password", admin.getPassWord(), 60 * 60 * 24 * 30);
            }
            //登陆成功，存入redis
            redisTemplate.boundHashOps(ADMIN).put(admin.getUserName(),admin);
            redisTemplate.expire(ADMIN,60, TimeUnit.MINUTES);
            //设置最后登录时间,登录次数,登录ip
            String ipAddr = IpUtils.getIpAddr(request);
            adminService.updateLastLogin(admin, ipAddr);
//            将token返回给前段
            return new Result("success", map);
        } else {
            return new Result("error", "用户名和密码错误");
        }
    }
    /**
     * 退出功能
     *
     * @return
     */
    @PostMapping("/logout")
    public Result logout(HttpServletRequest request) {
        String token = CookieUtils.getCookieValue(request, "token");
        CookieUtils.deleteCookie("token");
        //下线
        //解析token
        Claims claims = Jwts.parser().setSigningKey(sign).parseClaimsJws(token).getBody();
        String username = claims.get("username", String.class);
        redisTemplate.boundHashOps(ADMIN).delete(username);
        //登陆成功，存入redis中
        return new Result("success", "操作成功");
    }

    /**
     * 获取当前用户的菜单
     */
    @GetMapping("/getMenu")
    public Result getMenu() {
        //获取token
        String token = CookieUtils.getCookieValue(request, "token");
        //从当前token中获取登录用户的uid
        String uid = tokenDecode.decodeToken(token).get("jti");
        Map<String, Object> resultMap = adminService.getMenu(uid);
        return new Result("success", resultMap);
    }

    /**
     * 用户信息
     */
    @GetMapping("/info")
    public Result getInfo(String token) {
        String uid = tokenDecode.decodeToken(token).get("jti");
        Map<String, Object> resultMap = adminService.getInfo(uid);
        resultMap.put("token", token);
        return new Result("success", resultMap);
    }

    /**
     * 用户注册
     */
    @PostMapping("/register")
    public Result register(@RequestBody Map assignbody) {
        String ipAddr = IpUtils.getIpAddr(request);
        adminService.register(assignbody,ipAddr);
        return null;
    }

    /**
     * 更改用户密码
     */
    @PostMapping("/updatePassWord")
    public Result updatePassWord(String userInfo,String passWord,String newPassWord) {
        adminService.updatePassWord(userInfo,passWord,newPassWord);
        return new Result("success","更新成功");
    }
}
